import torch.nn.functional as F
import torch
import torch.nn as nn
import torch.nn.utils.rnn as rnn_utils
from torch.utils.data import Dataset, DataLoader
import pandas as pd
import numpy as np


def to_tensor(data, dtype="float", device="cpu") -> torch.Tensor:
    # Mapping from string dtype to actual torch dtype
    dtype_map = {
        "float": torch.float,
        "float32": torch.float,
        "float64": torch.double,
        "int": torch.int,
        "int32": torch.int,
        "int64": torch.long
    }

    if dtype not in dtype_map:
        raise ValueError(f"Unsupported dtype: {dtype}. Supported dtypes: {list(dtype_map.keys())}")

    torch_dtype = dtype_map[dtype]

    if isinstance(data, np.ndarray):
        tensor_data = torch.from_numpy(data)
    elif isinstance(data, pd.DataFrame):
        tensor_data = torch.from_numpy(data.values)
    elif isinstance(data, torch.Tensor):
        tensor_data = data
    else:
        raise ValueError(f"Invalid data type {type(data)}. Must be one of torch.Tensor, np.ndarray, or pd.DataFrame")

    return tensor_data.to(dtype=torch_dtype, device=device)